var fs = require("fs");
var readline = require('readline')
var async = require("async");
var LogItemDao = require("../dao/LogItemDao");
var logger = new require("../log/Logger")("FileProcessList");
var logTimeRegx = /^\[\d{4}\-\d{2}\-\d{2} \d{2}:\d{2}:\d{2}\.\d{0,3}\]/;
var levelRegx = /\[(info|debug|warning|error)\]/i;
var logModuleRegx = / [A-Za-z1-9_\.]+ \-/;

var FileProcessList = function(appName, collectionName) {
    var logItemDao = new LogItemDao(appName, collectionName);
    var isProcessing = false;
    var fileQueue = new Array();

    this.addFileToQueue = function(filePathName) {
        fileQueue.push(filePathName);
        process.nextTick(function() {
            startProcessQueue();
        });
    }

    function startProcessQueue() {
        if (!isProcessing && fileQueue.length > 0) {
            isProcessing = true;
            var asyncTasks = new Array();
            fileQueue.forEach(function(filePathName) {
                asyncTasks.push(function(callback) {
                    processLogFile(filePathName, callback);
                });
            });
            async.parallel(asyncTasks, function(err, result) {
                isProcessing = false;
                startProcessQueue();
            });

            fileQueue = new Array();
        }
    }

    function processLogFile(filePathName, callback) {
        fs.stat(filePathName, function(err, stats) {
            if (!err && stats.isFile()) {
                var logRead = readline.createInterface({
                    input: fs.createReadStream(filePathName)
                });
                var lineContent = "";
                logRead.on("line", function(logLine) {
                    if (logTimeRegx.test(logLine)) {
                        processLogLine(lineContent);
                        lineContent = logLine;
                    } else {
                        lineContent += logLine;
                    }
                });

                logRead.on("close", function() {
                    processLogLine(lineContent);

                    logger.info("processLogFile", "delete file====>>" + filePathName);
                    fs.unlink(filePathName);
                    if (callback) {
                        callback();
                    }
                });
            } else {
                if (callback) {
                    callback();
                }
                logger.error("processLogFile", filePathName + " is error!");
            }
        });
    }

    function processLogLine(logLine) {
        var timeStr = "";
        var logLevel = "";
        var moduleName = "";
        var logBody = "";
        var logBodyMD5 = "";
        var timeArea = logLine.match(logTimeRegx);
        if (timeArea != null) {
            timeStr = timeArea[0].substring(1, timeArea[0].length - 1).trim();
            logLine = logLine.replace(timeArea[0], "");
            var logLevelArea = logLine.match(levelRegx);
            if (logLevelArea != null) {
                logLevel = logLevelArea[0].substring(1, logLevelArea[0].length - 1).trim();
                logLine = logLine.replace(logLevelArea[0], "");
            }
            var logModuleArea = logLine.match(logModuleRegx);
            if (logModuleArea != null) {
                moduleName = logModuleArea[0].substring(1, logModuleArea[0].length - 1).trim();
                logLine = logLine.replace(logModuleArea[0], "").trim();
            }

            logItemDao.saveLog({
                timeStr: timeStr,
                levelStr: logLevel,
                moduleName: moduleName,
                content: logLine
            }).then(function(){
                //insert ok
            },function(){
                //insert error
            });
        } else {
            logger.error("processLogLine", logLine);
        }
    }

}
var processListMap = {};
FileProcessList.getFileProcessList = function(appName) {
    var processList = processListMap[appName];
    if (processList == null) {
        processList = new FileProcessList(appName);
        processListMap[appName] = processList;
    }
    return processList;
}

module.exports = FileProcessList;
